package com.openatc.optimize.fixedtimeplan.config.cross;

import com.openatc.model.model.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;


/**
 * @author mz
 * @version 1.0
 * @date 2021/8/20 14:34
 */
@Data
@NoArgsConstructor
@Builder
@AllArgsConstructor

public class CrossConfig {
    private String type;
    private long optcycle;
    private String name;
    private String agentid;
    private int red = 2;
    private int yellow = 3;
    private List<Ring> rings;
    private int loss = 3;
    private List<Barrier> barriers;
    private List<PhaseOpt> phases;

    //兼容处理
    private List<Phase> phaseList;
    private Pattern pattern;


    public void init(){
        if(rings != null){
            return;
        }
        rings = createRings();

        barriers = createBarriers();


        // 创建优化的相位

        // 兼容阶段模式
        if( pattern.getRings() == null || pattern.getRings().isEmpty() || "stage".equals(pattern.getContrloType())) {
            phases = new ArrayList<>();
            for( StageForStageMode stage : pattern.getStagesList() ){
                PhaseOpt phaseOpt = new PhaseOpt();
                phaseOpt.setId(stage.getKey() + 1);
                phaseOpt.setDuration(stage.getStageSplit() );
                phases.add(phaseOpt);
            }
        }else{
            if(phases == null)
                phases = new ArrayList<>();
            for(Phase phase:phaseList){
                int phaseId = phase.getId();
                PhaseOpt targetphase = phasebyid(phaseId);
                if(targetphase == null){
                    targetphase = new PhaseOpt();

                    targetphase.setId(phaseId);
                    phases.add(targetphase);
                }
                targetphase.setMingreen(phase.getMingreen());
                targetphase.setMaxgreen(phase.getMax1());
            }
            updatephases();
        }
    }



    private PhaseOpt phasebyid(int id){
        for(PhaseOpt phase:phases){
            if(phase.getId() == id){
                return phase;
            }
        }
        return null;
    }


    private List<Ring> createRings(){
        List<Ring> optrings = new LinkedList<>();

        List<List<Split>> rings;
        // 兼容阶段模式
        if( pattern.getRings() == null || pattern.getRings().isEmpty() || "stage".equals(pattern.getContrloType())){
            List<Split> splits = new ArrayList<>();
            for( StageForStageMode stage : pattern.getStagesList() ){
                Split split = new Split(stage.getKey() + 1, stage.getStageSplit(), 0);
                splits.add(split);
            }
            rings = new ArrayList<>();
            rings.add(splits);
            pattern.setContrloType("stage");
            pattern.setRings( rings );

        }else
            rings = pattern.getRings();

        for(int i=0; i < rings.size(); i++){
            List<Split> patternPhases = rings.get(i);
            List<Integer> sequence = new LinkedList<>();
            for(Split patternPhase:patternPhases){
                sequence.add(patternPhase.getId());
            }
            if(sequence.size() > 1){
                Ring ring = Ring.builder().sequence(sequence).num(i+1).build();
                optrings.add(ring);
            }

        }

        return optrings;
    }


    private List<Barrier> createBarriers(){
        List<Barrier> optbarriers = new LinkedList<>();

        // 兼容阶段模式
        if( pattern.getRings() == null || pattern.getRings().isEmpty() || "stage".equals(pattern.getContrloType())){
            return optbarriers;
        }

        List<BarrierFeature> barrierFeatures = pattern.getBarriers();
        if(barrierFeatures == null)
            return optbarriers;
        for(BarrierFeature barrierFeature : barrierFeatures){
            Barrier barrier = Barrier.createBarrierByBarrierFeature(barrierFeature);
            optbarriers.add(barrier);
        }
        return optbarriers;
    }


    private void updatephases(){
        for(List<Split> patternPhases : pattern.getRings()){
            for(Split patternPhase : patternPhases){
                int phaseId = patternPhase.getId();
                long duration = patternPhase.getValue();
                PhaseOpt phase = phasebyid(phaseId);
                if(phase != null){
                    phase.setDuration(duration);
                }


            }
        }
    }


}
